const express = require('express');
const bodyParser = require('body-parser');
const webpack = require('webpack');
const fs = require('fs');
const path = require('path');
const { v4: uuidv4 } = require('uuid');
const cors = require('cors');

// Initialize Express app
const app = express();
const port = 3000;

// Middleware to parse text/plain requests into raw string body
app.use(bodyParser.text({ type: '*/*' }));

app.use(cors());
/**
 * POST endpoint to compile user-submitted JavaScript code.
 *
 * The endpoint accepts raw JavaScript code as text/plain in the request body,
 * compiles it using Webpack and Babel to ensure compatibility and module resolution,
 * and returns the compiled code as a response.
 */
app.post('/compile', (req, res) => {
    // Extract user code from the request body
    const userCode = req.body;
    // Generate unique filenames for the source and output files
    const entryFileName = `src-${uuidv4()}.js`;
    const entryFilePath = path.resolve(__dirname, entryFileName);
    const outputFileName = `bundle-${uuidv4()}.js`;
    const outputFilePath = path.resolve(__dirname, outputFileName);

    // Write the user code to a temporary file
    fs.writeFileSync(entryFilePath, userCode);

    // Webpack configuration for compiling the user code
    const webpackConfig = {
        mode: 'development', // No optimization or minification
        entry: entryFilePath, // Entry file
        output: {
            path: __dirname, // Output directory
            filename: outputFileName, // Output file name
        },
        module: {
            rules: [
                {
                    test: /\.js$/, // Match JavaScript files
                    exclude: /node_modules/, // Exclude node_modules
                    use: {
                        loader: 'babel-loader', // Use Babel loader
                        options: {
                            presets: ['@babel/preset-env', '@babel/preset-react'], // Preset for compiling to ES5
                        },
                    },
                },
            ],
        },
    };

    // Compile the user code using Webpack
    webpack(webpackConfig, (err, stats) => {
        if (err || stats.hasErrors()) {
            // Log and return compilation errors
            console.error('Webpack compilation error:', err || stats.toJson().errors);
            res.status(500).send('Compilation error');

            // Cleanup: delete the temporary source and output files
            fs.unlinkSync(entryFilePath);
            fs.unlinkSync(outputFilePath);
            return;
        }

        // Read and send the compiled code as response
        const bundle = fs.readFileSync(outputFilePath, 'utf8');
        res.send(bundle);

        // Cleanup: delete the temporary source and output files
        fs.unlinkSync(entryFilePath);
        fs.unlinkSync(outputFilePath);
    });
});

// Start the Express server
app.listen(port, () => {
    console.log(`Server listening at http://localhost:${port}`);
});